security(7)

名称

security — FreeBSD下的安全性介绍

描述

有关FreeBSD中漏洞缓解的描述,请参阅缓 mitigations(7) (缓解措施)。本手册页记录了其他与FreeBSD安全相关的主题。

安全性是一个以系统管理员开始和结束的功能。虽然所有BSD多用户系统都有一些固有的安全性,但构建和维护额外的安全机制以保持用户“诚实”(honest)的工作可能是系统管理员最大的任务之一。机器的安全性取决于你制造它们的安全性,安全问题一直在与人类对便利性的需求竞争。一般来说,Unix系统能够同时运行大量进程,其中许多进程作为服务器运行,这意味着外部实体可以与它们连接和通信。随着昨天的微型计算机和大型机成为今天的台式机,随着计算机联网和互联网化,安全问题变得越来越大。

安全性最好通过分层洋葱(layered onion)方法来实现。简而言之,您要做的是创建尽可能多的安全层,然后仔细监控系统是否有入侵。

系统安全还涉及处理各种形式的攻击,包括试图崩溃或以其他方式使系统不可用但不试图破坏根的攻击。安全问题可分为几类:

  1. 拒绝服务攻击(Denial of Service attacks,DoS)
  2. 用户帐户泄露(compromises)
  3. 通过可访问的服务器进行根泄露(root compromises)
  4. 通过用户帐户进行根泄露
  5. 后门创建

compromises:n. 妥协;折中,和解;达成妥协;互让;v. 让步;使陷入危险;不达标

拒绝服务攻击是一种剥夺机器所需资源的行为。通常,DoS攻击是暴力破解机制,试图通过压倒服务器或网络堆栈来使机器崩溃或无法使用。一些DoS攻击试图利用网络堆栈中的漏洞,用单个数据包使机器崩溃。后者只能通过对内核应用bug修复来修复。对服务器的攻击通常可以通过适当指定选项来修复,以限制服务器在不利条件下对系统造成的负载。暴力网络攻击更难应对。例如,欺骗数据包攻击几乎不可能阻止您的系统与互联网的连接。它可能无法关闭你的机器,但它可以填满你的互联网管道。

用户帐户泄露甚至比DoS攻击更常见。一些系统管理员仍然在他们的机器上运行 telnetdftpd(8) 服务器。默认情况下,这些服务器不通过加密连接运行。其结果是,如果你有任何中等规模的用户群,那么从远程位置登录到你的系统的一个或多个用户(这是登录系统最常见和最方便的方式)的密码将被嗅探。细心的系统管理员会分析他的远程访问日志,寻找可疑的源地址,即使是成功登录。

必须始终假设,一旦攻击者访问了用户帐户,攻击者就可以破解root。然而,现实情况是,在一个安全和维护良好的系统中,访问用户帐户并不一定能让攻击者访问root。这种区别很重要,因为没有访问root的权限,攻击者通常无法隐藏自己的踪迹,充其量只能弄乱用户的文件或使机器崩溃。用户帐户泄露非常常见,因为用户往往不采取系统管理员采取的预防措施。

系统管理员必须记住,在机器上断开root可能有很多方法。攻击者可能知道root密码,攻击者可能会在root运行的服务器中发现一个错误,并能够通过与该服务器的网络连接断开root,或者攻击者可能知道SUID-root程序中的一个错误。如果攻击者找到了破解计算机root的方法,则攻击者可能不需要安装后门。迄今为止发现并关闭的许多root漏洞都涉及攻击者在自己之后清理的大量工作,因此大多数攻击者确实安装了后门。这为您提供了一种检测攻击者的便捷方法。让攻击者无法安装后门实际上可能对您的安全有害,因为它不会关闭攻击者最初用来闯入的漏洞。

安全补救措施应始终采用多层“洋葱皮”方法实施,可分为以下几类:

  1. 保护root账户和员工账户
  2. 保护root——root运行的服务器和SUID/SGID二进制文件
  3. 保护用户帐户
  4. 保护密码文件
  5. 保护内核核心、原始设备和文件系统
  6. 快速检测对系统所做的不适当更改
  7. 偏执狂

保护根帐户和保护员工帐户

如果您尚未保护根帐户,则无需费心保护员工帐户。大多数系统都为root帐户分配了密码。你要做的第一件事就是假设密码总是被泄露。这并不意味着您应该删除密码。密码几乎总是控制台访问机器所必需的。它的意思是,您不应该在控制台之外使用密码,甚至不应该使用 su(1) 实用程序。例如,确保你的PTY在 /etc/ttys 文件中被指定为 “insecure" (不安全),这样就不允许通过 telnet(1) 直接进行root登录。如果使用其他登录服务,如 sshd(8) ,请确保也禁用了直接root登录。考虑每种访问方法—— ftp(1) 等服务经常会出现漏洞。应只允许通过系统控制台直接进行root登录。

当然,作为一名系统管理员,你必须能够获得root权限,所以我们打开了一些漏洞。但我们确保这些漏洞需要额外的密码验证才能运行。使root可访问的一种方法是将适当的员工帐户添加到 wheel 组(在 /etc/group 中)。wheel 组中的工作人员允许 su(1) 入 root。您永远不应该通过将员工放入密码输入中的wheel组来授予他们本机wheel访问权限。员工帐户应放置在 staff 组中,然后通过 /etc/group 文件添加到wheel组中。只有那些真正需要root访问权限的工作人员才应被放置在wheel组中。在使用Kerberos等身份验证方法时,也可以在根帐户中使用Kerberos的 .k5login 文件,以允许 ksu(1) 进行根操作,而无需将任何人放入wheel组中。这可能是更好的解决方案,因为如果入侵者已经获取了您的密码文件,并且可以闯入员工帐户,那么wheel机制仍然允许入侵者破解根。虽然有wheel机制总比什么都没有好,但它不一定是最安全的选择。

保护root帐户的间接方法是使用另一种登录访问方法并为员工帐户输入加密密码来保护您的员工帐户。这样,入侵者可能能够窃取密码文件,但无法侵入任何员工帐户或root,即使root有一个加密的密码(当然,假设您对控制台的root访问权限有限)。工作人员通过使用私钥/公钥对的 kerberos(8)ssh(1) 等安全登录机制进入他们的员工帐户。当您使用类似Kerberos的东西时,通常必须保护运行Kerberos服务器的机器和您的桌面工作站。当您使用SSH的公钥/私钥对时,通常必须保护您从中登录的机器(通常是您的工作站),但您也可以在使用 ssh-keygen(1) 创建密钥对时通过密码保护密钥对来为密钥对添加额外的保护层。能够列出员工帐户的密码还可以保证员工只能通过您设置的安全访问方法登录。因此,您可以强制所有员工在所有会话中使用安全、加密的连接,从而关闭许多入侵者使用的一个重要漏洞:从无关、安全性较低的机器上嗅探网络。

更间接的安全机制还假设您从限制性更强的服务器登录到限制性较弱的服务器。例如,如果您的主机正在运行各种服务器,则您的工作站不应运行任何服务器。为了使您的工作站具有合理的安全性,您应该尽可能少地运行服务器,直至不运行服务器,并且应该运行密码保护的屏幕消隐器。当然,只要能够物理访问工作站,攻击者就可以破坏您在其上设置的任何类型的安全性。这绝对是一个您应该考虑的问题,但您也应该考虑这样一个事实,即绝大多数入侵都是通过网络从远程发生的,来自无法物理访问您的工作站或服务器的人。

使用Kerberos等工具,您还可以在一个地方禁用或更改员工帐户的密码,并使其立即影响员工可能拥有帐户的所有计算机。如果员工的帐户受到威胁,则不应低估在所有计算机上立即更改密码的能力。使用离散密码(discrete passwords),在N台机器上更改密码可能会很混乱。您还可以对Kerberos施加重新密码限制:不仅Kerberos票证可以在一段时间后超时,而且Kerberos系统可以要求用户在一定时间后(例如每月一次)选择新密码。

保护ROOT——ROOT-RUN服务器和SUID/SGID二进制文件

谨慎的系统管理员只运行他需要的服务器,不多也不少。请注意,第三方服务器通常是最容易出错的。例如,运行旧版本的 imapd(8)popper(8) (ports/mail/popper)就像给整个世界一个通用的root票(universal root ticket)。切勿运行未仔细检查过的服务器。许多服务器不需要以root身份运行。例如, talkd(8)comsat(8)fingerd(8) 守护进程可以在特殊的用户“沙盒”中运行。除非你遇到很多麻烦,否则沙盒并不完美,但洋葱式的安全方法仍然存在:如果有人能够通过运行在沙盒中的服务器入侵,他们仍然必须从沙盒中逃脱。攻击者必须突破的层次越多,成功的可能性就越低。历史上,几乎所有以Root身份运行的服务器都存在根漏洞,包括基本系统服务器。如果你运行的是一台人们只通过 sshd(8) 登录而从不通过 telnetd 登录的机器,那么请关闭此服务!

FreeBSD现在默认在沙箱中运行 talkd(8)comsat(8)fingerd(8) 。根据您是安装新系统还是升级现有系统,这些沙盒使用的特殊用户帐户可能不会安装。谨慎的系统管理员会尽可能为服务器研究和实施沙盒。

还有许多其他服务器通常不在沙盒中运行:sendmail(8)popper(8)imapd(8)ftpd(8) 等等。其中一些有替代方案,但安装它们可能需要比你愿意做的更多的工作(便利因素再次出现)。您可能必须以root身份运行这些服务器,并依靠其他机制来检测可能通过它们发生的入侵。

系统中另一个巨大的潜在根漏洞是安装在系统上的SUID-root和SGID二进制文件。这些二进制文件中的大多数,如 su(1) ,都位于 /bin/sbin/usr/bin/usr/sbin 中。虽然没有什么是100%安全的,但系统默认的SUID和SGID二进制文件可以被认为是相当安全的。尽管如此,在这些二进制文件中偶尔会发现root hole。1998年在Xlib中发现了一个root hole,使 xterm(1)ports/x11/xterm)(通常是SUID)容易受到攻击。安全总比后悔好,谨慎的系统管理员会将只有员工才能运行的SUID二进制文件限制在只有员工才能访问的特殊组中,并删除( chmod 000 )任何没有人使用的SUID文件。没有显示器的服务器通常不需要 xterm(1)ports/x11/xterm)二进制文件。SGID二进制文件几乎同样危险。如果入侵者可以破解SGID-kmem二进制文件,入侵者可能能够读取 /dev/kmem,从而读取加密的密码文件,这可能会危及任何密码帐户。或者,破坏组 kmem 的入侵者可以监视通过PTY发送的按键,包括通过安全方法登录的用户使用的PTY。破坏 tty 组的入侵者几乎可以写入任何用户的TTY。如果用户正在运行具有键盘模拟功能的终端程序或模拟器,入侵者可能会生成一个数据流,导致用户的终端回显命令,然后以该用户的身份运行。

保护用户帐户

用户帐户通常是最难保护的。虽然你可以对你的员工施加严格的访问限制,并删除他们的密码,但你可能无法使用你可能拥有的任何普通用户帐户。如果你确实有足够的控制权,那么你可能会胜出,并能够正确保护用户帐户。如果没有,你只需要在监控这些账户时更加警惕。由于需要额外的管理和技术支持,对用户帐户使用SSH和Kerberos更成问题,但与加密密码文件相比,这仍然是一个非常好的解决方案。

保护密码文件

唯一可靠的方法是尽可能多地输入密码,并使用SSH或Kerberos访问这些帐户。即使加密的密码文件(/etc/spwd.db)只能由root读取,即使攻击者无法获得root写入权限,入侵者也可能获得对该文件的读取权限。

您的安全脚本应始终检查并报告密码文件的更改(请参阅下面的“CHECKING FILE INTEGRITY,检查文件完整性”)。

保护内核核心、原始设备和文件系统

如果攻击者破坏了root,他几乎可以做任何事情,但也有一些便利。例如,大多数现代内核都内置了数据包嗅探设备驱动程序。在FreeBSD下,它被称为 bpf(4) 设备。入侵者通常会尝试在受感染的机器上运行数据包嗅探器。你不需要给入侵者提供这种能力,大多数系统都不应该编译 bpf(4) 设备。

但即使你关闭了 bpf(4) 设备,你仍然需要担心 /dev/mem/dev/kmem 。就此而言,入侵者仍然可以写入原始磁盘设备。此外,还有另一个内核特性,称为模块加载器 kldload(8) 。有进取心的入侵者可以使用KLD模块在正在运行的内核上安装自己的 bpf(4) 设备或其他嗅探设备。为了避免这些问题,您必须在更高的安全级别上运行内核,至少是级别 1 。可以使用 kern.securevel 变量上的 sysctl(8) 设置安全级别。一旦将安全级别设置为 1 ,对原始设备的写访问将被拒绝,并且将强制执行特殊的 chflags(1) 标志,如 schg 。您还必须确保在关键的启动二进制文件、目录和脚本文件上设置 schg 标志——所有运行到设置安全级别的文件。这可能有些过头了,当您在更高的安全级别下操作时,升级系统要困难得多。您可以妥协并以更高的安全级别运行系统,但不要为阳光下的每个系统文件和目录设置 schg 标志。另一种可能是简单地以只读方式挂载 //usr 。应该指出的是,在试图保护的方面过于严厉可能会阻止对入侵的重要检测。

内核以五个不同的安全级别运行。任何超级用户进程都可以提高级别,但没有进程可以降低级别。安全级别是:

可以使用 rc.conf(5) 中记录的变量配置安全级别。

检查文件完整性:二进制文件、配置文件等

归根结底,在方便因素浮出水面之前,你只能保护你的核心系统配置和控制文件这么多。例如,使用 chflags(1)//usr 中的大多数文件上设置 schg 位可能会适得其反,因为虽然它可以保护文件,但它也会关闭一个检测窗口。安全洋葱的最后一层可能是最重要的——检测(detection)。如果你无法检测到潜在的入侵,那么你的其他安全措施几乎毫无用处(或者更糟糕的是,给你一种虚假的安全感)。洋葱的一半工作是减缓攻击者的速度,而不是阻止他,以便让检测层有机会当场抓住他。

检测入侵的最佳方法是查找修改(modified)、丢失(missing)或意外(unexpected)的文件。查找修改文件的最佳方式是从另一个(通常是集中式的,centralized)有限访问系统中查找。在额外安全的受限访问系统上编写安全脚本,使其对潜在攻击者几乎不可见,这一点很重要。为了最大限度地利用优势,您通常必须赋予受限访问箱(limited-access box)对业务中其他机器的重要访问权限,通常是通过将其他机器以只读NFS方式导出到受限访问箱,或者通过设置SSH密钥对来允许受限访问箱通过SSH连接到其他机器。除了网络流量外,NFS是最不可见的方法——允许您几乎不被察觉地监视每个客户端上的文件系统。如果您的受限访问服务器通过交换机连接到客户端,则NFS方法通常是更好的选择。如果您的受限访问服务器通过集线器或通过多层路由连接到客户端,则NFS方法可能太不安全(网络方面),即使使用SSH铺设的审计跟踪,使用SSH也可能是更好的选择。

一旦你给了一个限制访问框至少对它应该监视的客户端系统的读取权限,你就必须编写脚本来进行实际的监视。给定NFS挂载,你可以用简单的系统实用程序(如 find(1)md5(1) )编写脚本。最好每天至少对客户端文件箱进行一次物理 md5(1) ,并更频繁地测试 /etc//usr/local/etc 中的控制文件。当发现与受限访问机器知道有效的基本MD5信息不匹配时,它应该向系统管理员发出尖叫,让他去检查。一个好的安全脚本还将检查不合适的SUID二进制文件以及系统分区(如 //usr)上的新文件或已删除文件。

当使用SSH而不是NFS时,编写安全脚本要困难得多。您基本上必须将脚本 scp(1) 到客户端框中才能运行它们,使其可见,为了安全起见,您还需要 scp(1) 这些脚本使用的二进制文件(如 find(1) )。客户端上的 sshd(8) 守护进程可能已经受到攻击。总而言之,在不安全的链接上运行时,使用SSH可能是必要的,但也很难处理。

一个好的安全脚本还将检查用户和工作人员访问配置文件的更改:.rhosts.shosts.ssh/authorized_keys 等,这些文件可能不在MD5检查的范围内。

如果您有大量的用户磁盘空间,则可能需要很长时间才能运行这些分区上的每个文件。在这种情况下,设置挂载标志以禁止这些分区上的SUID二进制文件是一个好主意。 nosuid 选项(请参阅 mount(8) )是您想要查看的内容。无论如何,我都会每周至少扫描一次,因为这一层的目的是检测入侵是否有效。

进程会计(process accounting,见 accton(8) )是操作系统的一个相对较低的开销特性,我建议将其用作中断后的评估机制。它在追踪入侵者是如何实际入侵系统的方面特别有用,假设入侵发生后文件仍然完好无损。

最后,安全脚本应该处理日志文件,日志本身应该以尽可能安全的方式生成——远程syslog可能非常有用。入侵者试图掩盖其踪迹,日志文件对于试图追踪首次闯入的时间和方法的系统管理员来说至关重要。一种永久记录日志文件的方法是将系统控制台运行到串行端口,并通过监控控制台的安全机器持续收集信息。

偏执狂

有点偏执(paranoia)是不会有坏处的。通常,系统管理员可以添加任意数量的安全功能,只要它们不影响便利性,并且可以添加一些影响便利性的安全功能。更重要的是,安全管理员应该把它搞混一点——如果你逐字逐句地使用本手册页给出的建议,你就把你的方法论交给了也可以访问本手册页的潜在攻击者。

DoS攻击专题

本节介绍拒绝服务攻击。DoS攻击通常是数据包攻击。虽然你对饱和网络的现代欺骗数据包攻击无能为力,但你通常可以通过确保攻击不会使你的服务器瘫痪来限制损害。

  1. 限制服务器分叉
  2. 限制跳板攻击(ICMP响应攻击、ping广播等)
  3. 内核路由缓存

一种常见的DoS攻击是针对分叉服务器(forking server)的,它试图使服务器吃掉进程、文件描述符和内存,直到机器死亡。 inetd(8) 服务器有几个选项来限制这种攻击。应该注意的是,虽然可以防止机器停机,但通常不可能防止服务被攻击中断。请仔细阅读 inetd(8) 手册页,并特别注意 -c-C-R 选项。请注意,欺骗性IP攻击将绕过 inetd(8)-C 选项,因此通常必须使用多个选项的组合。一些独立服务器具有自分叉限制(self-fork-limitation)参数。

sendmail(8) 守护进程有其 −OMaxDaemonChildren 选项,由于负载滞后,该选项往往比尝试使用 sendmail(8) 的负载限制选项要好得多。当您启动 sendmail(8) 时,您应该指定一个 MaxDaemonChildren 参数,该参数足够高以处理预期的负载,但不要太高,以至于计算机无法处理那么多的sendmail而不会崩溃。谨慎的做法是在“queued”模式下运行 sendmail(8)-ODeliveryMode=queued ),并将守护进程(sendmail −bd )与队列运行(sendmail -q15m )分开运行。如果你仍然想要实时传递,你可以以更低的间隔运行队列,例如 -q1m ,但一定要为该 sendmail(8) 指定一个合理的 MaxDaemonChildren 选项,以防止级联失败(cascade failures)。

syslogd(8) 守护进程可能会被直接攻击,强烈建议您尽可能使用 -s 选项,否则使用 -a 选项。

您还应该相当小心地使用连接回服务,例如tcpwrapper的反向识别,这可能会直接受到攻击。出于这个原因,您通常不希望使用tcpwrappers的反向识别功能。

通过在边界路由器上设置防火墙来保护内部服务免受外部访问是一个非常好的主意。这里的想法是防止来自局域网外部的饱和攻击,而不是保护内部服务免受基于网络的根攻击。始终配置专用防火墙,即“防火墙端口A、B、C、D和M-Z之外的所有端口”。通过这种方式,您可以防火墙关闭所有低端口,但某些特定服务除外,如 talkd(8)sendmail(8) 和其他互联网可访问的服务。如果你试图以另一种方式配置防火墙——作为包容性或许可性防火墙,你很可能会忘记“关闭”一些服务,或者你会添加一个新的内部服务,却忘记更新防火墙。您仍然可以在防火墙上打开编号较高的端口范围,以允许类似许可的操作,而不会影响您的低端口。另外请注意,FreeBSD允许您通过各种 net.inet.ip.portrange sysctl(sysctl net.inet.ip.portrange)控制用于动态绑定的端口号范围,这也可以降低防火墙配置的复杂性。我通常使用4000到5000的正常首末范围和49152到65535的hiport范围,然后在防火墙中阻止4000以下的所有内容(当然,某些特定的互联网可访问端口除外)。

另一种常见的DoS攻击称为跳板攻击——以一种导致服务器生成响应的方式攻击服务器,然后使服务器、本地网络或其他机器过载。这种性质的最常见攻击是ICMP PING广播(BROADCAST)攻击。攻击者伪造发送到局域网广播地址的ping数据包,源IP地址设置为他们想要攻击的实际机器。如果你的边界路由器没有配置为踩踏(stomp on)ping来广播地址,你的局域网最终会对欺骗的源地址产生足够的响应,使受害者饱和,尤其是当攻击者同时在几十个不同的网络上对几十个广播地址使用相同的伎俩时。已经测量到超过120兆比特的广播攻击。第二种常见的跳板攻击是针对ICMP错误报告系统的。通过构建生成ICMP错误响应的数据包,攻击者可以使服务器的传入网络饱和,并使服务器的传出网络充满ICMP响应。这种类型的攻击还可以通过在 mbuf 之外运行服务器来崩溃服务器,特别是如果服务器无法足够快地耗尽它生成的ICMP响应。FreeBSD内核有一个新的内核编译选项,称为 ICMP_BANDLIM ,它限制了这些攻击的有效性。最后一类主要的跳板攻击与某些内部 inetd(8) 服务有关,如UDP回声服务。攻击者只需伪造一个UDP数据包,其中源地址是服务器A的回声端口(echo port),目标地址是服务器B的回声端口(服务器A和B都在您的局域网上)。然后,这两个服务器在彼此之间来回反弹这个数据包。攻击者只需以这种方式注入一些数据包,就可以使服务器及其局域网过载。内部chargen端口也存在类似的问题。有能力的系统管理员将关闭所有这些 inetd(8) 内部测试服务。

KERBEROS和SSH的访问问题

如果您打算使用Kerberos和SSH,则需要解决它们的一些问题。Kerberos5是一个优秀的身份验证协议,但 kerberized telnet(1) 很糟糕。有些bug使它们不适合处理二进制流。此外,默认情况下,除非使用 -x 选项,否则Kerberos不会加密会话。SSH默认加密所有内容。

SSH在各个方面都工作得很好,除非它被设置为转发加密密钥。这意味着,如果你有一个持有密钥的安全工作站,可以访问系统的其他部分,并且你通过 ssh(1) 连接到一台不安全的机器,你的密钥就会暴露出来。实际的密钥本身不会暴露,但 ssh(1) 会在您登录期间安装一个转发端口,如果攻击者在不安全的机器上破坏了根,他可以利用该端口使用您的密钥来访问您的密钥解锁的任何其他机器。

我们建议您尽可能将SSH与Kerberos结合用于员工登录。SSH可以在Kerberos支持下编译。这减少了您对可能暴露的SSH密钥的依赖,同时通过Kerberos保护密码。SSH密钥只能用于来自安全机器的自动化任务(Kerberos不适合这样做)。我们还建议您在SSH配置中关闭密钥转发,或者使用SSH在其 authorized_keys 文件中允许的 from=IP/DOMAIN 选项,使密钥仅可用于从特定计算机登录的实体。

旋钮和微调

FreeBSD提供了几个旋钮(knobs)和微调手柄(tweak handles),使一些内省信息的访问更加受限。有些人认为这可以提高系统安全性,因此这里简要列出了旋钮,以及能够缓解硬件状态泄漏的控制措施。

下文所述的硬件缓解sysctl旋钮已移至 machdep.mitigations 下,并带有向后兼容性(backwards-compatibility)垫片(shims)以接受现有名称。未来的更改将使单个系统的感觉合理化(因此 enabled/true 始终表示缓解措施处于活动状态)。因此,前面的名称仍然是设置缓解措施的规范方式,并在此处记录。将不添加 machdep.mitigations 下临时系统的向后兼容性垫片。

参阅

chflags(1) , find(1) , md5(1) , netstat(1) , openssl(1) , proccontrol(1) , ps(1) , ssh(1) , xdm(1)(ports/x11/xorg-clients), group(5), ttys(5), mitigations(7), accton(8), init(8), sshd(8), sysctl(8), syslogd(8), vipw(8)

历史

security 手册页最初由Matthew Dillon编写,首次出现在1998年12月的FreeBSD 3.1中。